﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HaumDisplay
{
    public class HaumRotateRect : HaumShape
    {
        /// <summary>
        /// 中心点
        /// </summary>
        public PointF center;

        /// <summary>
        /// 宽
        /// </summary>
        public float widthHalf;

        /// <summary>
        /// 高
        /// </summary>
        public float heightHalf;

        /// <summary>
        /// 角度
        /// </summary>
        public double angle;

        internal Pen pen;

        /// <summary>
        /// 反色
        /// </summary>
        internal Color invertColor;
        
        /// <summary>
        /// 是否选中
        /// </summary>
        internal bool isSelect;

        /// <summary>
        /// 开始绘制
        /// </summary>
        internal bool startGraphic;

        public HaumRotateRect(Color color, int borderSize = 1) {
            this.center = PointF.Empty;
            this.widthHalf = 0;
            this.heightHalf = 0;
            this.angle = 0;
            this.pen = new Pen(color, borderSize);
            //this.invertColor = Color.FromArgb(255 - color.R, 255 - color.G, 255 - color.B);
            this.invertColor = Color.FromArgb(color.R / 2, color.G / 2, color.B / 2);
            this.isSelect = false;
            this.startGraphic = false;
        }

        /// <summary>
        /// 获取面积
        /// </summary>
        /// <returns></returns>
        public float GetArea() {
            return (widthHalf * 2) * (heightHalf * 2);
        }

        /// <summary>
        /// 获取左上角点坐标
        /// </summary>
        /// <returns></returns>
        public PointF GetTL() {
            // 将角度转换为弧度
            double rad = this.angle * Math.PI / 180.0;

            // 计算旋转矩阵的正弦和余弦值
            double cosAngle = Math.Cos(rad);
            double sinAngle = Math.Sin(rad);

            PointF tl = new PointF(-this.widthHalf, -this.heightHalf);
            // 应用旋转公式
            float rotatedX = (float)(tl.X * cosAngle - tl.Y * sinAngle);
            float rotatedY = (float)(tl.X * sinAngle + tl.Y * cosAngle);

            // 加上中心点坐标，得到最终位置
            tl.X = this.center.X + rotatedX;
            tl.Y = this.center.Y + rotatedY;

            return tl;
        }

        /// <summary>
        /// 获取右上角点坐标
        /// </summary>
        /// <returns></returns>
        public PointF GetTR()
        {
            // 将角度转换为弧度
            double rad = this.angle * Math.PI / 180.0;

            // 计算旋转矩阵的正弦和余弦值
            double cosAngle = Math.Cos(rad);
            double sinAngle = Math.Sin(rad);


            PointF tr = new PointF(this.widthHalf, -this.heightHalf);
            // 应用旋转公式
            float rotatedX = (float)(tr.X * cosAngle - tr.Y * sinAngle);
            float rotatedY = (float)(tr.X * sinAngle + tr.Y * cosAngle);

            // 加上中心点坐标，得到最终位置
            tr.X = this.center.X + rotatedX;
            tr.Y = this.center.Y + rotatedY;

            return tr;
        }

        /// <summary>
        /// 获取右下角点坐标
        /// </summary>
        /// <returns></returns>
        public PointF GetBR()
        {
            // 将角度转换为弧度
            double rad = this.angle * Math.PI / 180.0;

            // 计算旋转矩阵的正弦和余弦值
            double cosAngle = Math.Cos(rad);
            double sinAngle = Math.Sin(rad);


            PointF br = new PointF(this.widthHalf, this.heightHalf);
            // 应用旋转公式
            float rotatedX = (float)(br.X * cosAngle - br.Y * sinAngle);
            float rotatedY = (float)(br.X * sinAngle + br.Y * cosAngle);

            // 加上中心点坐标，得到最终位置
            br.X = this.center.X + rotatedX;
            br.Y = this.center.Y + rotatedY;

            return br;
        }

        /// <summary>
        /// 获取左下角点坐标
        /// </summary>
        /// <returns></returns>
        public PointF GetBL()
        {
            // 将角度转换为弧度
            double rad = this.angle * Math.PI / 180.0;

            // 计算旋转矩阵的正弦和余弦值
            double cosAngle = Math.Cos(rad);
            double sinAngle = Math.Sin(rad);


            PointF bl = new PointF(-this.widthHalf, this.heightHalf);
            // 应用旋转公式
            float rotatedX = (float)(bl.X * cosAngle - bl.Y * sinAngle);
            float rotatedY = (float)(bl.X * sinAngle + bl.Y * cosAngle);

            // 加上中心点坐标，得到最终位置
            bl.X = this.center.X + rotatedX;
            bl.Y = this.center.Y + rotatedY;

            return bl;
        }

        /// <summary>
        /// 计算可旋转矩形的四个角点坐标
        /// </summary>
        /// <param name="center">矩形中心点坐标</param>
        /// <param name="widthRadius">宽度的一半（宽半径）</param>
        /// <param name="heightRadius">高度的一半（高半径）</param>
        /// <param name="angle">旋转角度（度），顺时针为正</param>
        /// <returns>矩形四个角点的坐标列表</returns>
        public PointF[] GetCorners()
        {
            // 将角度转换为弧度
            double rad = this.angle * Math.PI / 180.0;

            // 计算旋转矩阵的正弦和余弦值
            double cosAngle = Math.Cos(rad);
            double sinAngle = Math.Sin(rad);

            // 矩形四个顶点相对于中心的原始坐标（未旋转时）
            PointF[] corners = new PointF[4]
            {
                new PointF( -this.widthHalf, -this.heightHalf ),  // 左上角
                new PointF( this.widthHalf, -this.heightHalf ),   // 右上角
                new PointF( this.widthHalf, this.heightHalf ),  // 右下角
                new PointF( -this.widthHalf, this.heightHalf ), // 左下角
            };

            for (int i = 0; i < corners.Length; i++) {
                float x = corners[i].X;
                float y = corners[i].Y;

                // 应用旋转公式
                float rotatedX = (float)(x * cosAngle - y * sinAngle);
                float rotatedY = (float)(x * sinAngle + y * cosAngle);

                // 加上中心点坐标，得到最终位置
                corners[i].X = this.center.X + rotatedX;
                corners[i].Y = this.center.Y + rotatedY;
            }

            return corners;
        }

        /// <summary>
        /// 获取左边中心点
        /// </summary>
        /// <returns></returns>
        public PointF GetLeftCenter() {
            PointF tl = this.GetTL();
            PointF bl = this.GetBL();
            return new PointF((tl.X + bl.X) / 2, (tl.Y + bl.Y) / 2);
        }

        /// <summary>
        /// 获取右边中心点
        /// </summary>
        /// <returns></returns>
        public PointF GetRightCenter()
        {
            PointF tr = this.GetTR();
            PointF br = this.GetBR();
            return new PointF((tr.X + br.X) / 2, (tr.Y + br.Y) / 2);
        }

        /// <summary>
        /// 获取上边中心点
        /// </summary>
        /// <returns></returns>
        public PointF GetTopCenter()
        {
            PointF tl = this.GetTL();
            PointF tr = this.GetTR();
            return new PointF((tl.X + tr.X) / 2, (tl.Y + tr.Y) / 2);
        }

        /// <summary>
        /// 获取下边中心点
        /// </summary>
        /// <returns></returns>
        public PointF GetBottomCenter() {
            PointF bl = this.GetBL();
            PointF br = this.GetBR();
            return new PointF((bl.X + br.X) / 2, (bl.Y + br.Y) / 2);
        }

        public override string ToString()
        {
            return $"旋转矩形中心坐标:[{center.X},{center.Y}]-宽半径:[{widthHalf.ToString("f3")}]-高半径:[{heightHalf.ToString("f3")}]-旋转角度:[{angle.ToString("f3")}]-" +
                $"角点坐标[" +
                $"[{this.GetTR().X},{this.GetTR().Y}]-" +
                $"[{this.GetTL().X},{this.GetTL().Y}]-" +
                $"[{this.GetBR().X},{this.GetBR().Y}]-" +
                $"[{this.GetBL().X},{this.GetBL().Y}]]";
        }

        public override void Graphic(Graphics g, GraphicHelper myGraphic)
        {
            g.SmoothingMode = SmoothingMode.HighQuality;
            //绘制矩形
            PointF[] corners = this.GetCorners();
            List<PointF> cornersScr = new List<PointF>();
            for (int i = 0; i < corners.Length; i++)
            {
                cornersScr.Add(Tools.ImageTransScreenPointF(corners[i], myGraphic.scale, myGraphic.offset));
            }
            g.DrawPolygon(this.pen, cornersScr.ToArray());

            //绘制圆心小十字
            //获取圆心像素坐标 转换成控件坐标
            PointF center = Tools.ImageTransScreenPointF(this.center, myGraphic.scale, myGraphic.offset);
            //根据中心坐标拟合两条垂直线
            // 绘制垂直的线（中心点上下各 3 像素）
            g.DrawLine(this.pen, center.X, center.Y - 5, center.X, center.Y + 5);
            // 绘制水平的线（中心点左右各 3 像素）
            g.DrawLine(this.pen, center.X - 5, center.Y, center.X + 5, center.Y);


            using (Brush brush = new SolidBrush(this.isSelect ? this.invertColor : this.pen.Color))
            {
                float r = this.pen.Width * 3;

                //PointF tr = Tools.ImageTransScreenPointF(this.GetTR(), myGraphic.scale, myGraphic.offset); //旋转点
                //g.FillEllipse(brush, tr.X - r / 2, tr.Y - r / 2, r, r);

                //PointF rc = Tools.ImageTransScreenPointF(this.GetRightCenter(), myGraphic.scale, myGraphic.offset);
                //g.FillEllipse(brush, rc.X - r / 2, rc.Y - r / 2, r, r);

                //PointF bc = Tools.ImageTransScreenPointF(this.GetBottomCenter(), myGraphic.scale, myGraphic.offset);
                //g.FillEllipse(brush, bc.X - r / 2, bc.Y - r / 2, r, r);
            }
        }

    }
}
